package com.ruoyi.mongo.utils;

import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.*;

import java.util.List;
import java.util.Map;

public class MongoUtils {
    /**
     * 按分组字段（如 category）分组，每组随机返回 1 条唯一数据
     * @param groupField 分组字段名（如 "category"）
     * @param mongoTemplate 查询的数据库（如 "category"）
     * @return 分组字段值 -> 随机数据的映射
     */
    public static List<Map> getRandomUniqueByGroup(String groupField, MongoTemplate mongoTemplate, String collectionName) {
        // 1. 按分组字段分组（如按 category 分组）
        GroupOperation group = Aggregation.group(groupField)
                .push("$$ROOT") // 将组内所有文档存入数组（字段名为 "items"）
                .as("items");

        // 2. 对每个组内的数组随机取 1 条数据（确保组内唯一）
        // $arrayElemAt: 取数组中指定索引的元素
        // $rand(): 生成 0-1 之间的随机数，乘以数组长度后取整得到随机索引
        String randomExpr = "{$arrayElemAt: [$items,{$floor: {$multiply: [{$rand: {}}, {$size: '$items'}]}}]}";

        // 3. 构建聚合管道
        Aggregation aggregation = Aggregation.newAggregation(
                group, // 第一步：分组
                Aggregation.project()
                        .and(groupField).previousOperation() // 保留分组字段
                        .andExpression(randomExpr).as("randomItem") // 添加随机项
        );

        // 4. 执行聚合查询
        AggregationResults<Map> aggregate = mongoTemplate.aggregate(
                aggregation,
                collectionName, // 集合名
                Map.class
        );

        return aggregate.getMappedResults();
    }


    // 适用于 MongoDB 5.2+ 的简化写法
    public static  <T> List<T> getRandomOrderByGroup(String groupField,MongoTemplate mongoTemplate, Class<T> entityClass) {
        GroupOperation group = Aggregation.group(groupField)
                .push("$$ROOT").as("groupItems")
                // 组内随机取1条（MongoDB 5.2+ 支持）

                .first("randomOrder.0").as("randomOrder"); // 取数组第0条

        Aggregation aggregation = Aggregation.newAggregation(
                group,
                Aggregation.project()
                        .and(groupField).previousOperation()
                        .and("randomOrder").as("randomOrder")
        );

        return mongoTemplate.aggregate(aggregation, "orders", entityClass).getMappedResults();
    }

    /**
     * 从集合中随机获取指定数量的文档
     * @param collectionName 集合名称
     * @param limit 随机获取的数量
     * @param entityClass 实体类类型
     * @return 随机文档列表
     */
    public static  <T> List<T> getRandomDocuments(String collectionName, MongoTemplate mongoTemplate, int limit, Class<T> entityClass) {
        // 1. 构建聚合管道：使用$sample随机取样
        Aggregation aggregation = Aggregation.newAggregation(
                Aggregation.sample(limit) // 随机获取limit条数据
        );

        // 2. 执行聚合查询
        AggregationResults<T> results = mongoTemplate.aggregate(
                aggregation,
                collectionName,
                entityClass
        );

        return results.getMappedResults();
    }
}
